package com.tuananh.radnom.persist.imp.xml;

import java.util.ArrayList;
import java.util.HashMap;

import com.ajexperience.utils.DeepCopyException;
import com.ajexperience.utils.DeepCopyUtil;
import com.tuananh.radnom.model.NetElementConfiguration;
import com.tuananh.radnom.model.NetInterface;
import com.tuananh.radnom.model.NetNode;
import com.tuananh.radnom.model.iputils.IPRange;
import com.tuananh.radnom.model.netservice.NetService;
import com.tuananh.radnom.model.utils.IPUtils;
import com.tuananh.radnom.persist.DaoContainer;
import com.tuananh.radnom.persist.INetIntDAO;

public class NetIntXmlDAO extends XmlDAO implements INetIntDAO {
	NetElementConfiguration netConfig;

	public NetIntXmlDAO() {
		super(NetElementConfiguration.path);
		configuration = XmlConfigHolder.neConfig;
		try {
			savedConfiguration = (new DeepCopyUtil()).deepCopy(configuration);
		} catch (DeepCopyException e) {
			// TODO Auto-generated catch block
			savedConfiguration = new NetElementConfiguration();
			e.printStackTrace();
		}
		netConfig = (NetElementConfiguration) configuration;
	}

	public boolean add(NetInterface netInt, String nodeName) {
		// TODO Auto-generated method stub
		NetNodeXmlDAO nodeDAO = (NetNodeXmlDAO) DaoContainer.listDAO
				.get(NetNodeXmlDAO.class.getName());
		if (nodeName != null) {
			NetNode node = nodeDAO.getByName(nodeName);
			for (NetInterface item : node.getNetInterfaces()) {
				if (item.getName().equals(netInt.getName()))
					return false;
			}
			node.getNetInterfaces().add(netInt);
		} else {

		}
		// Report event
		reportEvent(netInt,
				generateHeaders("METHOD_NAME", "add", "NODE_NAME", nodeName));
		return true;
	}

	public boolean update(NetInterface netInt) {
		// TODO Auto-generated method stub
		NetNodeXmlDAO nodeDAO = (NetNodeXmlDAO) DaoContainer.listDAO
				.get(NetNodeXmlDAO.class.getName());
		NetNode node = nodeDAO.findByIntName(netInt.getName());
		if (node == null) {
			NetInterface sameIpNetInt = getByIp(netInt.getIpAddress());
			node = nodeDAO.findByIntName(sameIpNetInt.getName());
			netInt.setName(sameIpNetInt.getName());
		}
		for (int i = 0; i < node.getNetInterfaces().size(); i++)
			if (node.getNetInterfaces().get(i).getName()
					.equals(netInt.getName())) {
				node.getNetInterfaces().set(i, netInt);

				reportEvent(
						netInt,
						generateHeaders("METHOD_NAME", "update", "status",
								"succeed"));
				return true;
			}
		reportEvent(netInt,
				generateHeaders("METHOD_NAME", "update", "status", "failed"));
		return false;
	}

	public boolean remove(String name) {
		// TODO Auto-generated method stub
		NetNodeXmlDAO nodeDAO = (NetNodeXmlDAO) DaoContainer.listDAO
				.get(NetNodeXmlDAO.class.getName());
		NetNode node = nodeDAO.findByIntName(name);
		for (int i = 0; i < node.getNetInterfaces().size(); i++)
			if (node.getNetInterfaces().get(i).getName().equals(name)) {
				reportEvent(
						node.getNetInterfaces().get(i),
						generateHeaders("METHOD_NAME", "remove", "status",
								"succeed"));
				node.getNetInterfaces().remove(i);
				return true;
			}
		reportEvent("constant",
				generateHeaders("METHOD_NAME", "update", "status", "failed"));
		return false;
	}

	public ArrayList<NetInterface> getAll() {
		// TODO Auto-generated method stub
		ArrayList<NetInterface> listNetInt = new ArrayList<NetInterface>();
		ArrayList<NetNode> listNode = netConfig.getListNode();
		for (NetNode node : listNode)
			listNetInt.addAll(node.getNetInterfaces());
		return listNetInt;
	}

	public NetInterface getByName(String name) {
		// TODO Auto-generated method stub
		NetNodeXmlDAO nodeDAO = (NetNodeXmlDAO) DaoContainer.listDAO
				.get(NetNodeXmlDAO.class.getName());
		NetNode node = nodeDAO.findByIntName(name);
		for (int i = 0; i < node.getNetInterfaces().size(); i++)
			if (node.getNetInterfaces().get(i).getName().equals(name))
				return node.getNetInterfaces().get(i);
		return null;
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return "NetIntEvent";
	}

	public ArrayList<NetInterface> getByNames(String names) {
		// TODO Auto-generated method stub
		if (names == null)
			return null;
		NetNodeXmlDAO nodeDAO = (NetNodeXmlDAO) DaoContainer.listDAO
				.get(NetNodeXmlDAO.class.getName());
		ArrayList<NetInterface> all = getAll();
		ArrayList<NetInterface> result = new ArrayList<NetInterface>();
		for (NetInterface netInt : all)
			if (names.contains(netInt.getName())) {
				result.add(netInt);
			}
		return result;
	}

	public ArrayList<NetInterface> getByRange(IPRange range) {
		// TODO Auto-generated method stub
		if (range == null)
			return null;
		ArrayList<NetInterface> all = getAll();
		ArrayList<NetInterface> result = new ArrayList<NetInterface>();
		for (int i = 0; i < all.size(); i++) {
			NetInterface netInt = all.get(i);
			if (IPUtils.inRange(range, netInt.getIpAddress())) {
				result.add(netInt);
			}
		}
		return result;
	}

	public NetInterface getByIp(String ip) {
		// TODO Auto-generated method stub
		ArrayList<NetInterface> list = getAll();
		for (NetInterface netInt : list) {
			if (netInt.getIpAddress().trim().equals(ip.trim()))
				return netInt;
		}
		return null;
	}

	NetService containService(ArrayList<NetService> list, String serviceName) {
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).getName().equals(serviceName))
				return list.get(i);
		}
		return null;
	}

	public boolean merge(NetInterface first, NetInterface second) {
		// TODO Auto-generated method stub
		if (first.getMacAddress() == null)
			first.setMacAddress(second.getMacAddress());
		for (NetService service : second.getNetServices()) {
			NetService temp = containService(first.getNetServices(),
					service.getName());
			if (temp != null) {
				if (service.getParams() != null)
					temp.getParams().putAll(service.getParams());
			} else
				first.getNetServices().add(service);
		}
		return true;
	}
}
